<template>
  <div ref="chartRef" :style="{ height, width }"></div>
</template>

<script lang="ts">
  import { defineComponent, PropType, Ref, ref, watchEffect } from 'vue';
  import { useECharts } from '/@/hooks/web/useECharts';
  import * as MathUtil from '/@/utils/MathUtil';

  const COLOR_RED = '#F53F3F';

  export default defineComponent({
    name: 'RingImg',
    props: {
      width: {
        type: String as PropType<string>,
        default: '100%',
      },
      height: {
        type: String as PropType<string>,
        default: '200px',
      },
      dataList: {
        type: Array as PropType<{ name: string; value: number; color: string }[]>,
        required: true,
      },
      centerPoint: {
        type: Array as unknown as PropType<[string, string]>,
        default: () => ['50%', '50%'],
      },
    },
    setup(props) {
      const chartRef = ref<HTMLDivElement | null>(null);
      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);

      const percent2DFormatter = (value: number, dot = 2) => {
        return MathUtil.percent2DFormatter(value, dot);
      };

      const renderItem = (params: any, api: any) => {
        const values = [api.value(0), api.value(1)];
        const coord = api.coord(values);
        const size = api.size([1, 1], values);
        const dataIndexInside = params.dataIndexInside;
        const dataIndex = params.dataIndex;
        const dataInsideLength = params.dataInsideLength;
        const canvasWidth = api.getWidth();
        const canvasHeight = api.getHeight();
        const textX = canvasWidth * 0.95;
        const textY = canvasHeight * 0.1 * (dataInsideLength - dataIndexInside);
        const coord1 = api.coord([values[0], parseFloat(values[1] / 6)]);
        const value = api.value(1);
        const isNegative = value < 0;
        return {
          type: 'group',
          children: [
            {
              type: 'sector', // 环形扇区
              z2: 1,
              shape: {
                cx: params.coordSys.cx,
                cy: params.coordSys.cy,
                r0: coord[2] - size[0] / 6, // 半径偏移量
                r: coord[2] + size[0] / 6,
                startAngle: -(Math.PI / 2),
                endAngle: Math.PI * 1.5,
                clockwise: value >= 0,
              },
              style: api.style({
                fill: '#F7F8FA',
              }),
            },
            {
              type: 'sector',
              z2: 2,
              shape: {
                cx: params.coordSys.cx,
                cy: params.coordSys.cy,
                r0: coord[2] - size[0] / 6,
                r: coord[2] + size[0] / 6,
                startAngle: -(Math.PI / 2),
                endAngle: Math.abs(value) > 1 ? Math.PI * 1.5 : -coord[3],
                clockwise: value >= 0,
              },
              style: api.style({
                fill: api.value(2),
                shadowBlur: isNegative ? 5 : 0,
                shadowColor: COLOR_RED,
                stroke: isNegative ? COLOR_RED : 'none',
                lineWidth: isNegative ? 2 : 0,
              }),
            },
            {
              type: 'text',
              style: {
                text: `${props.dataList[dataIndex].name}`,
                x: textX - 40,
                y: textY,
                fontSize: 13,
                // fontWeight: 600,
                textAlign: 'right',
                // fill: api.value(2),
                fill: '#000',
              },
            },
            {
              type: 'text',
              style: {
                text: `${percent2DFormatter(api.value(1), 1)}`,
                x: textX + 5,
                y: textY,
                fontSize: 13,
                // fontWeight: 600,
                textAlign: 'right',
                fill: isNegative ? COLOR_RED : '#000',
              },
            },
            {
              type: 'rect',
              shape: {
                x: textX,
                y: textY + 16,
                width: 3,
                height: 3,
              },
              style: {
                fill: isNegative ? COLOR_RED : '#000',
              },
            },
            {
              type: 'rect',
              z2: 100,
              shape: {
                x: coord1[0],
                y: coord1[1] - 2,
                width: 3,
                height: 3,
              },
              style: {
                fill: isNegative ? COLOR_RED : '#000',
              },
            },
            {
              type: 'polyline',
              z2: 100,
              shape: {
                points: [
                  [coord1[0], coord1[1]],
                  [textX - 84, textY + 18],
                  [textX, textY + 18],
                ],
              },
              style: {
                fill: null,
                stroke: isNegative ? COLOR_RED : '#000',
                lineWidth: 0.5,
              },
            },
          ],
          silent: true,
        };
      };

      const getOption = () => {
        return {
          polar: {
            center: props.centerPoint,
          },
          angleAxis: {
            type: 'value',
            show: false,
            boundaryGap: false,
            min: 0,
            max: 1,
            interval: 45,
          },
          radiusAxis: {
            type: 'category',
            show: false,
            data: props.dataList.map((g) => g.name),
            z: 100,
          },
          series: [
            {
              type: 'custom',
              coordinateSystem: 'polar',
              renderItem: renderItem,
              data: props.dataList.map((g, index) => [index, g.value, g.color]),
            },
          ],
        };
      };

      watchEffect(() => {
        if (props.dataList.length > 0) {
          setOptions(getOption());
        }
      });

      return { chartRef };
    },
  });
</script>
